// @(#)mutex.cc
// Time-stamp: <2008-12-14 16:02:13 root>
// Copyright 2008 Julian Qian
// Author: root@localhost.localdomain
// Version: $Id: mutex.cc,v 0.0 2008/10/07 18:31:59 root Exp $
// Keywords: 
//

// #include "common.hh"
#include "mutex.hh"
// #include "log.hh"


MutEX::MutEX(MUTEX_NP np){
    // PTHREAD_MUTEX_FAST_NP
    // PTHREAD_MUTEX_RECURSIVE_NP
    // PTHREAD_MUTEX_ERRORCHECK_NP
    switch(np){
    case FAST:
		ASSERT(0 == pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_FAST_NP));        
        break;
    case RECU:
		ASSERT(0 == pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE_NP));
        break;
    case ECHK:
		ASSERT(0 == pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK_NP));
        break;
    }

    pthread_mutex_init(&mutex, &attr);
    pthread_cond_init(&cond, NULL);
    
    sem_init(&sem, 0, 0);

    flag = 0;
}

MutEX::~MutEX(){
    pthread_mutexattr_destroy(&attr);
	pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    sem_destroy(&sem);
}

void
MutEX::lock(){
    
	ASSERT(0 == pthread_mutex_lock(&mutex));
}

bool
MutEX::trylock(){
    if(0 == pthread_mutex_trylock(&mutex)){
        return true;
    }else{
        return false;
    }
}

void
MutEX::unlock(){
	ASSERT(0 == pthread_mutex_unlock(&mutex));
}

void
MutEX::wait(){
    sem_wait(&sem);
}

bool
MutEX::trywait(){
    if(0 == sem_trywait(&sem)){
        return true;
    }else{
        return false;
    }
}

void
MutEX::post(){
    sem_post(&sem);
}

void
MutEX::cwait(){
    while(!flag){
        pthread_cond_wait(&cond, &mutex);
    }
}

void
MutEX::signal(){
    flag = 1;
    pthread_cond_signal(&cond);
}
